package ma.ensao.egicom.core.dao.implementations;

import java.util.List;

import ma.ensao.egicom.core.dao.interfaces.ProductDAO;
import ma.ensao.egicom.core.model.Product;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Order;
import org.scub.foundation.framework.core.dao.implementations.HibernateDaoBaseImplementation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ProductDAOImpl extends HibernateDaoBaseImplementation implements ProductDAO {
    private static final Logger log = LoggerFactory.getLogger(ProductDAO.class);

    // property constants
    public static final String ID = "id";

    public static final String LABEL = "label";

    public static final String DESCRIPTION = "description";

    public static final String IMAGE = "image";

    public static final String PRICE = "price";

    public static final String CATEGORYID = "categoryid";

    // other constants
    public static final int NEW_PRODUCT_LIMIT = 10;

    /**
     * {@inheritDoc}
     */
    @Override
    public void save(Product transientInstance) {
        super.save(transientInstance);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void delete(Product persistentInstance) {
        delete(persistentInstance);

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Product findById(java.lang.Long id) {
        return load(id, Product.class);
    }

    public List findByProperty(String propertyName, Object value) {
        log.debug("finding Product instance with property: " + propertyName + ", value: " + value);
        try {
            String queryString = "from Product as model where model." + propertyName + "= ?";
            Query queryObject = createQuery(queryString);
            queryObject.setParameter(0, value);
            return queryObject.list();
        } catch (RuntimeException re) {
            log.error("find by property name failed", re);
            throw re;
        }
    }

    public List findById(Object id) {
        return findByProperty(ID, id);
    }

    public List findByLabel(Object label) {
        return findByProperty(LABEL, label);
    }

    public List findByPrice(Object price) {
        return findByProperty(PRICE, price);
    }

    public List findByCategory(int category) {
        return findByProperty(CATEGORYID, category);
    }

    public List findAll() {
        return loadAll(Product.class);
    }

    @Override
    public List<Product> findNewProducts() {
        Criteria criteria = createCriteria(Product.class);
        criteria.addOrder(Order.desc("insertiondate"));
        criteria.setMaxResults(NEW_PRODUCT_LIMIT);
        return criteria.list();
    }

}
